﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using XNA_Game_Engine;
using XNA_Game_Engine.Characters;
using XNA_Game_Engine.Map;
using XNA_Game_Engine.GUI;
using System.Collections.Generic;
using XNA_Game_Engine.Events;
using XNA_Game_Engine.Sounds;
        
namespace MenesDroid.EngineCharacter
{
    class Enemy : Character
    {
        private IsometricTilemap map;
        public int XDir, YDir;
        private float timer = 0;
        private Boolean jumping = false;
        float time = 0;
        private int enemyRadar = 3;
        private bool canWalk = false;
        public int enemyXInicial;
        public int enemyYInicial;
        public int enemyXDirInicial;
        public int enemyYDirInicial;
        private bool followingPath = false;
        private List<PlayerPath> plrPath = new List<PlayerPath>();
        private int index = 0;
        private AnimatedSprite Sprite;

        public Enemy(int x, int y, AnimatedSprite sprite, IsometricTilemap tileMap)
        {
            this.x = x;
			this.y = y;
            this.Sprite = sprite;
            this.map = tileMap;
            Angle = 27;
            Speed = 0;
            Width = sprite.GetWidth();
            Height = sprite.GetHeight();
            //this.XDir = 1;
            //this.YDir = 0;
            enemyXInicial = x;
            enemyYInicial = y;
            //enemyXDirInicial = XDir;
            //enemyYDirInicial = YDir;
            //setDirectionFrame();
            //playerPath = new List<Vector2>();
        }


        public override void Update(float gameTime)
        {
            OldX = x; OldY = y;            
            setDirectionFrame();          
        }
        
        public override void Render( SpriteBatch renderTarget )
        {
            int borderDistance = 5;
            float posY = (float) y ;
            float posX = (float) x;

            float tx = (float) ((posX * map.TileWidth / 2) + (posY * map.TileWidth / 2) + map.X) + 9 + borderDistance;
            float ty = (float)((posY * (map.TileHeigth - 9) / 2) - (posX * (map.TileHeigth - 9) / 2) + map.Y) - Height/2;

            if(jumping)
            {
                tx -= 2;
                ty -= 10;
            }

          Sprite.Render(renderTarget, tx, ty);
        }
        
        public void verifyEnemyProximity(float difftime, Vector2 plrPosition, Vector2 plrDirection)
        {
            double xDistancia = Math.Abs(plrPosition.X - this.X);
            double yDistancia = Math.Abs(plrPosition.Y - this.Y);
            
            if (StaticGui.gameStarted)
            {
                time += difftime;
                verifyFreeToWalk(); // Verifica se inimigo pode andar. 1 em 1 segundo.               

                if ((xDistancia <= enemyRadar) && (yDistancia <= enemyRadar) && canWalk) // Se esta na area de visao. O pau pegará !!
                {
                    savePlayerPath(plrPosition, plrDirection);

                    if (plrPosition.Y >= this.y || plrPosition.Y <= this.y)
                    {
                        if (((this.y <= plrPath[0].PlrPosition.Y) || (this.y >= plrPath[0].PlrPosition.Y)) && !followingPath)
                        {                            
                            moveAhead();
                            verifyIsInsidePath(); // Se inimigo entrou no path. Set true e anda pelo path.
                        }
                        else
                        {
                            moveEnemieByPath(); // Andando pelo path
                        }
                    }

                }
            }
            else
            {
                restartVariables();
            }
        }

        private void verifyIsInsidePath()
        {
            if (this.y == plrPath[0].PlrPosition.Y && this.x == plrPath[0].PlrPosition.X)
            {
                followingPath = true;
            }
            else
            {
                for (int i = 0; i < plrPath.Count; i++)
                {
                    if (this.y == plrPath[i].PlrPosition.Y && this.x == plrPath[i].PlrPosition.X)
                    {
                        followingPath = true;
                        index = i - 1;
                    }
                }
            }
        }

        private void moveEnemieByPath()
        {            
            index++;    
            this.XDir = (int)plrPath[index].PlrDirection.X;
            this.YDir = (int)plrPath[index].PlrDirection.Y;
            this.x = plrPath[index].PlrPosition.X;
            this.y = plrPath[index].PlrPosition.Y;                   
        }

        private void savePlayerPath(Vector2 plrPos, Vector2 plrDir)
        {
            PlayerPath newPlrPath = new PlayerPath(plrPos, plrDir);
            if (!plrPath.Contains(newPlrPath))
            {
                plrPath.Add(newPlrPath); //Adiciona o path do player.
            }
        }

        private void verifyFreeToWalk()
        {
            if (time > 1000)
            {
                time = 0;
                canWalk = true;
            }
            else
                canWalk = false;
        }

        public void restartVariables()
        {            
            time = 0;            
            followingPath = false;
            index = 0;
            plrPath.Clear();            
        }

        private void setDirectionFrame()
        {            
            if (this.XDir == 0 && this.YDir == 1)
                Sprite.SetFrameLine(2, 1); //BAIXO

            if (this.XDir == 1 && this.YDir == 0)
                Sprite.SetFrameLine(3, 1); //DIREITA

            if (this.XDir == 0 && this.YDir == -1)
                Sprite.SetFrameLine(1, 1); //CIMA

            if (this.XDir == -1 && this.YDir == 0)
                Sprite.SetFrameLine(0, 1); //ESQUERDA                      
        }

        public void setEnemySpawnDirectionFrame(Vector2 plrPosition)
        {
         
            #region Directions
            if (this.X < plrPosition.X)
            {
                if (this.X - plrPosition.X > -2)
                {
                    this.XDir = 1; this.YDir = 0; // Console.WriteLine("1");// DIREITA                     
                }
                else
                {
                    if (this.Y - plrPosition.Y > -2 && this.Y - plrPosition.Y < 0)
                    {
                        this.XDir = 0; this.YDir = 1; //Console.WriteLine("2");//BAIXO
                    }
                    else
                    {
                        if (this.Y - plrPosition.Y < 0)
                        {
                            this.XDir = 1; this.YDir = 0;// Console.WriteLine("3");  //DIREITA
                        }
                        if (this.Y - plrPosition.Y > 2)
                        {
                            this.XDir = 0; this.YDir = -1; //Console.WriteLine("4"); //CIMA
                        }
                        else
                        {
                            if (this.Y - plrPosition.Y > 0)
                            {
                                this.XDir = 1; this.YDir = 0;// Console.WriteLine("5");//DIREITA
                            }
                        }
                    }
                }
            }
            else
            {
                if (this.X - plrPosition.X > 2)
                {
                    this.XDir = -1; this.YDir = 0; //Console.WriteLine("6");// ESQUERDA
                }
                else
                {
                    if (this.Y - plrPosition.Y > -2 && this.Y - plrPosition.Y < 0)
                    {
                        this.XDir = 0; this.YDir = 1; //Console.WriteLine("7"); //BAIXO
                    }
                    else
                    {
                        if (this.Y - plrPosition.Y < 0)
                        {
                            this.XDir = -1; this.YDir = 0;// Console.WriteLine("8");//ESQUERDA
                        }
                        if (this.Y - plrPosition.Y > 2)
                        {
                            this.XDir = 0; this.YDir = -1;// Console.WriteLine("9");//CIMA
                        }
                        else
                        {
                            if (this.Y - plrPosition.Y > 0)
                            {
                                this.XDir = -1; this.YDir = 0; //Console.WriteLine("10");//ESQUERDA
                            }
                        }
                    }
                }
            }
            

            if (plrPosition.X == this.X)
            {
                if (plrPosition.Y > this.Y)
                {
                    this.XDir = 0; this.YDir = 1; //Console.WriteLine("11"); //BAIXO                    
                }
                else
                {
                    this.XDir = 0; this.YDir = -1; //Console.WriteLine("12"); //CIMA
                }
            }

            if (plrPosition.Y == this.Y)
            {
                if (plrPosition.X > this.X)
                {
                    this.XDir = 1; this.YDir = 0; //Console.WriteLine("13");//DIREITA                  
                }
                else
                {
                    this.XDir = -1; this.YDir = 0; //Console.WriteLine("14");//ESQUERDA
                }
            }
            #endregion

            setDirectionFrame();

            this.enemyXDirInicial = XDir;
            this.enemyYDirInicial = YDir;

        }

        public void restartOriginalPositions()
        {
            this.x = this.enemyXInicial;
            this.Y = this.enemyYInicial;
            this.XDir = this.enemyXDirInicial;
            this.YDir = this.enemyYDirInicial;
        }

        #region Enemy Moviments

        public bool isJumping()
        {
            return jumping;
        }
        
        public void moveAhead()
        {
            this.x += XDir;
            this.y += YDir;

            mapBounds();
        }

        public void moveBack()
        {
            this.x += -XDir;
            this.y += -YDir;

            mapBounds();
        }

        public void jumpAhead()
        {
            jumping = true;
            moveAhead();

        }

        public void jumpOff()
        {
            jumping = false;
            moveAhead();
        }

        public void jumpFalse()
        {
            jumping = false;
        }

        public void turnLeft()
        {
            float xAng = XDir;
            float yAng = YDir;
            float angulo = MathHelper.ToRadians(90);
            float coseno = (float)Math.Cos(angulo);
            float seno = (float)Math.Sin(angulo);

            XDir = (int)(xAng * coseno + yAng * seno);
            YDir = (int)(-xAng * seno + yAng * coseno);
        }

        public void turnRight()
        {
            float xAng = XDir;
            float yAng = YDir;
            float angulo = MathHelper.ToRadians(90);
            float coseno = (float)Math.Cos(angulo);
            float seno = (float)Math.Sin(angulo);

            XDir = (int)(xAng * coseno - yAng * seno);
            YDir = (int)(xAng * seno + yAng * coseno);
        }

        #endregion

        private void mapBounds()
        {
            this.x = this.x >= 9 ? 9 : this.x;
            this.y = this.y >= 9 ? 9 : this.y;
            this.x = this.x < 0 ? 0 : this.x;
            this.y = this.y < 0 ? 0 : this.y;
        }

        private void KeyboardInputEvents(float gameTime)
        {
            Speed = 0;
            timer += gameTime;

            if (timer >= 100)
            {
                if (Keyboard.GetState().IsKeyDown(Keys.W))
                {
                    moveAhead();
                }
                if (Keyboard.GetState().IsKeyDown(Keys.S))
                {
                    moveBack();
                }
                if (Keyboard.GetState().IsKeyDown(Keys.A))
                {
                    turnLeft();
                }

                if (Keyboard.GetState().IsKeyDown(Keys.D))
                {
                    turnRight();
                }

                if (Keyboard.GetState().IsKeyDown(Keys.Space))
                {
                    jumpAhead();
                }


                timer = 0;
            }
        }

        public int oldX
        {
            get { return (int)OldX; }
        }

        public int oldY
        {
            get { return (int)OldY; }
        }


       

    } // end of PlayerCharacter class
} //  MenesDroid.Character namespace
